/*
 * ConfigureServer.java
 *
 * Created on 29 de Julho de 2007, 16:41
 */

package org.gpp.proj1.ui.gui.lobby;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.ListModel;

import org.gpp.proj1.communication.CommunicationException;
import org.gpp.proj1.communication.listener.ConnectionAttemptListener;
import org.gpp.proj1.ui.gui.SRGGUIView;

/**
 *
 * @author  Gustavo
 */
public class SCRConfigureServer extends javax.swing.JFrame implements ConnectionAttemptListener {
    
    /**
     *
     */
    private static final long serialVersionUID = 2361546993491321755L;
    
    private static final String MAPS_ROOT = "./res/map/";
    private static final String MAP_FILE_EXTENSION = ".map";
    
    private File[] mapFiles;
    private String[] mapNames;

	private final SRGGUIView view;
    
    /** Creates new form ConfigureServer */
    public SCRConfigureServer( SRGGUIView view ) {
        this.view = view;
		this.loadMaps();
        initComponents();
        
        if ( this.mapsList.getModel().getSize() > 0 ) {
            this.mapsList.setSelectedIndex( 0 );
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        instructionLabel = new javax.swing.JLabel();
        nameLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        mapLabel = new javax.swing.JLabel();
        jScrollPane = new javax.swing.JScrollPane();
        mapsList = new javax.swing.JList();
        maxPlayersLabel = new javax.swing.JLabel();
        portLabel = new javax.swing.JLabel();
        portTextField = new javax.swing.JTextField();
        cancelButton = new javax.swing.JButton();
        confirmButton = new javax.swing.JButton();
        maxPlayersComboBox = new javax.swing.JComboBox();
        clientPortLabel = new javax.swing.JLabel();
        clientPortTextField = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("SomeRobotGame");
        setResizable(false);
        instructionLabel.setText("Configure server");

        nameLabel.setText("Name:");

        nameTextField.setText("My server");
        this.nameTextField.selectAll();

        mapLabel.setText("Start map:");

        mapsList.setModel(getMapsListModel());
        mapsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        mapsList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                mapsListValueChanged(evt);
            }
        });

        jScrollPane.setViewportView(mapsList);

        maxPlayersLabel.setText("Max players:");

        portLabel.setText("Port:");

        portTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        portTextField.setText("27015");
        portTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                portTextFieldFocusGained(evt);
            }
        });

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        confirmButton.setText("Confirm");
        confirmButton.setEnabled(false);
        confirmButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                confirmButtonActionPerformed(evt);
            }
        });

        maxPlayersComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "2", "3", "4", "5", "6" }));

        clientPortLabel.setText("Client port:");

        clientPortTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        clientPortTextField.setText("25016");
        clientPortTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                clientPortTextFieldFocusGained(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(mapLabel)
                    .add(layout.createSequentialGroup()
                        .add(cancelButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 171, Short.MAX_VALUE)
                        .add(confirmButton))
                    .add(instructionLabel)
                    .add(nameLabel)
                    .add(layout.createSequentialGroup()
                        .add(jScrollPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 160, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(15, 15, 15)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                            .add(maxPlayersLabel)
                            .add(maxPlayersComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 88, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(clientPortTextField)
                            .add(portTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 90, Short.MAX_VALUE)
                            .add(portLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .add(clientPortLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 40, Short.MAX_VALUE))
                    .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 252, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(instructionLabel)
                .add(19, 19, 19)
                .add(nameLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(15, 15, 15)
                .add(mapLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(maxPlayersLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(maxPlayersComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(27, 27, 27)
                        .add(portLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(portTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(17, 17, 17)
                        .add(clientPortLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(clientPortTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(jScrollPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 174, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 41, Short.MAX_VALUE)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(cancelButton)
                    .add(confirmButton))
                .addContainerGap())
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void clientPortTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_clientPortTextFieldFocusGained
        this.clientPortTextField.selectAll();
    }//GEN-LAST:event_clientPortTextFieldFocusGained

    private void confirmButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_confirmButtonActionPerformed
        try {
            String name = this.nameTextField.getText().trim();
            int port = Integer.parseInt( this.portTextField.getText().trim() );
            int clientPort = Integer.parseInt( this.clientPortTextField.getText().trim() );
            int maxPlayers = Integer.parseInt( (String)this.maxPlayersComboBox.getSelectedItem() );
            int index = this.mapsList.getSelectedIndex();
        
            
            SCRLobby lobby = new SCRLobby( this.view, true );
            
            view.getController().startServer( name, maxPlayers, this.mapNames[ index ], this.mapFiles[ index ], port );            
            view.getController().connectToServer( this, "localhost:" + port, clientPort );            
            
            lobby.setVisible(true);
            this.dispose();
        } catch ( NumberFormatException nfe ) {
            JOptionPane.showMessageDialog( this, "Invalid port.", "Error", JOptionPane.ERROR_MESSAGE);
            nfe.printStackTrace();
        } catch ( IllegalArgumentException iae ) {
            JOptionPane.showMessageDialog( this, iae.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            iae.printStackTrace();
        } catch (CommunicationException e) {
        	JOptionPane.showMessageDialog( this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        	e.printStackTrace();
		}
    }//GEN-LAST:event_confirmButtonActionPerformed

    private void mapsListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_mapsListValueChanged
        
        if ( this.mapsList.getSelectedIndex() == -1 ) {
            this.confirmButton.setEnabled( false );
        }
        else {
            this.confirmButton.setEnabled( true );
        }
    }//GEN-LAST:event_mapsListValueChanged

    private void portTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_portTextFieldFocusGained
        this.portTextField.selectAll();
    }//GEN-LAST:event_portTextFieldFocusGained

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        SCRClientServer cs = new SCRClientServer( this.view );
        cs.setVisible(true);
        this.dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed
    
    private ListModel getMapsListModel() {
        
        DefaultListModel model = new DefaultListModel();
        for ( String s : this.mapNames ) {
            model.addElement( s );
        }

        return model;
    }

    private void loadMaps() {

        List<File> l = new LinkedList<File>();        
        File dir = new File( MAPS_ROOT );
                
        for ( File f : dir.listFiles() ) {
            if ( f.isFile() && !f.isHidden() && f.getName().toLowerCase().endsWith( MAP_FILE_EXTENSION )) {
                l.add(f);
            }
        }        
        
        this.mapFiles = l.toArray( new File[]{} );
        this.mapNames = new String[ this.mapFiles.length ];
        for ( int i = 0; i < this.mapNames.length; i++ ) {
            this.mapNames[i] = this.mapFiles[i].getName().substring(0, this.mapFiles[i].getName().lastIndexOf( MAP_FILE_EXTENSION ));
        }        
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JLabel clientPortLabel;
    private javax.swing.JTextField clientPortTextField;
    private javax.swing.JButton confirmButton;
    private javax.swing.JLabel instructionLabel;
    private javax.swing.JScrollPane jScrollPane;
    private javax.swing.JLabel mapLabel;
    private javax.swing.JList mapsList;
    private javax.swing.JComboBox maxPlayersComboBox;
    private javax.swing.JLabel maxPlayersLabel;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JLabel portLabel;
    private javax.swing.JTextField portTextField;
    // End of variables declaration//GEN-END:variables

	public void connectionAttemptFailed( String errorMessage ) {
		
		JOptionPane.showMessageDialog( this, "Could not connect to local server:" +
				"\"" + errorMessage + "\"", "Error", JOptionPane.ERROR_MESSAGE );
	}

	public void connectionAttemptSucceeded() {
		
		JOptionPane.showMessageDialog( this, "Connected to server", "Connected", JOptionPane.INFORMATION_MESSAGE );
	}
    
}
